﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MadLibrary.Math
{
    /// <summary>
    /// Represents percentage in code.
    /// </summary>
    public partial class Percentage
    {
        /// <summary>
        /// Gets or sets percentage for base or value calculation.
        /// </summary>
        public double Value { get; set; }
        /// <summary>
        /// Creates new empty Percentage object instance.
        /// </summary>
        public Percentage()
        {
            this.Value = 0.0;
        }
        /// <summary>
        /// Creates new percentage with specified value.
        /// </summary>
        /// <param name="Percentage">Specifies value of new percentage.</param>
        public Percentage(double Percentage)
        {
            this.Value = Percentage;
        }
        /// <summary>
        /// Creates new percentage with calculated percentage.
        /// </summary>
        /// <param name="Base">Specifies base for percentage calculation</param>
        /// <param name="Value">Specifies value for percentage calculation.</param>
        public Percentage(double Base, double Value)
        {
            this.Value = Math.Percentage.GetPercentage(Base, Value);
        }
        /// <summary>
        /// Calculates base from current percentage with specified value.
        /// </summary>
        /// <param name="Value">Specifies value which equals current percentage.</param>
        /// <returns>Base of current percentage.</returns>
        public double GetBase(double Value)
        {
            return Percentage.GetBase(this.Value, Value);
        }
        /// <summary>
        /// Calculates value from current percentage wuth specified base.
        /// </summary>
        /// <param name="Base">Specifies base which is used as base for current percentage.</param>
        /// <returns>Vale of current percentage.</returns>
        public double GetValue(double Base)
        {
            return Percentage.GetValue(Base, this.Value);
        }

        /// <summary>
        /// Returns string built from current percentage object.
        /// </summary>
        /// <returns>String built from current percentage object.</returns>
        public override string ToString()
        {
            return this.Value.ToString() + "%";
        }
    }
    public partial class Percentage
    {
        /// <summary>
        /// Calculates base from specified percentage and value.
        /// </summary>
        /// <param name="Percentage">Specifies percentage for base calculation.</param>
        /// <param name="Value">Specifies value for base calculation.</param>
        /// <returns>Calculated base from specified percentage and value.</returns>
        public static double GetBase(double Percentage, double Value)
        {
            return Value / Percentage * 100;
        }
        /// <summary>
        /// Calculates percentage from specified base and value.
        /// </summary>
        /// <param name="Base">Specifies base for percentage calculation.</param>
        /// <param name="Value">Specifies value for percentage calculation.</param>
        /// <returns>Calculated percentage from specified base and value.</returns>
        public static double GetPercentage(double Base, double Value)
        {
            return Value / Base * 100;
        }
        /// <summary>
        /// Calculates percentage from specified base and value.
        /// </summary>
        /// <param name="Base">Specifies base for percentage calculation.</param>
        /// <param name="Value">Specifies value for percentage calculation.</param>
        /// <param name="Percentage">Specifies new Percentage object which has to be filled with calculated percentage.</param>
        /// <returns>Calculated percentage from specified base and value.</returns>
        public static double GetPercentage(double Base, double Value, out Percentage Percentage)
        {
            Percentage = new Percentage(Value / Base * 100);
            return Percentage.Value;
        }
        /// <summary>
        /// Calculates value from specified base and percentage.
        /// </summary>
        /// <param name="Base">Specifies base for value calculation.</param>
        /// <param name="Percentage">Specifies percentage for value calculation.</param>
        /// <returns>Calculated value from specified base and percentage.</returns>
        public static double GetValue(double Base, double Percentage)
        {
            return Base * Fraction.FromDecimal(Percentage, 100.0);
        }
    }
    public partial class Percentage
    {
        /// <summary>
        /// Implicitly converts specified double variable to percentage.
        /// </summary>
        /// <param name="percentage">Specifies double variable which has to be converted to percentage.</param>
        /// <returns>Percentage converted from specified double variable.</returns>
        public static implicit operator Percentage(double percentage)
        {
            return new Percentage(percentage);
        }
        /// <summary>
        /// Implicitly converts specified percentage variable to double.
        /// </summary>
        /// <param name="percentage">Specifies percentage variable which has to be converted to double.</param>
        /// <returns>Double converted from specified percentage variable.</returns>
        public static implicit operator double(Percentage percentage)
        {
            return percentage.Value;
        }
    }
}
